package org.rpgmapper;

import java.io.File;
import java.util.List;

import org.rpgmapper.adapter.DragShadowBuilder;
import org.rpgmapper.bo.Character;
import org.rpgmapper.bo.Hero;
import org.rpgmapper.database.RPGMapperOpenHelper;
import org.rpgmapper.skirmish.SkirmishManager;
import org.rpgmapper.view.CharacterView;

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PorterDuff;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.DragEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnDragListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;


public class PlacePlayersActivity extends Activity {

	private final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 31;
	
	private LayoutInflater inflater;
	private Character selectedCharacter;
	private EditText editTextName;
	private CharacterView characterView;
	private View dialogLayout;
    private Character droppedCharacter = null;
    private RPGMapperOpenHelper helper;
    private Uri imageUri;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        
        this.inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		setContentView(R.layout.select_player_side);
		
		findViewById(R.id.arrow_u).setOnDragListener(onDragPCListener);
		findViewById(R.id.arrow_d).setOnDragListener(onDragPCListener);
		findViewById(R.id.arrow_r).setOnDragListener(onDragPCListener);
		findViewById(R.id.arrow_l).setOnDragListener(onDragPCListener);
		findViewById(R.id.trash).setOnDragListener(onDragPCListener);
		findViewById(R.id.add_char).setOnDragListener(onDragPCListener);
		findViewById(R.id.add_char).setOnClickListener(onClickAddCharacterListener);

        ((GridView)findViewById(R.id.PCs_for_sides)).setAdapter(new PCSidesAdapter(this));
        ((GridView)findViewById(R.id.PCs_for_sides)).setOnItemClickListener(onClickListener);
        ((GridView)findViewById(R.id.PCs_for_sides)).setOnItemLongClickListener(onLongClickListener);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
			    if (resultCode == RESULT_OK) {
			    	Cursor cursor = null;
			    	try {
			    	    String [] proj={MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID, MediaStore.Images.ImageColumns.ORIENTATION};
			    	    cursor = this.managedQuery( imageUri,
			    	            proj, // Which columns to return
			    	            null,       // WHERE clause; which rows to return (all rows)
			    	            null,       // WHERE clause selection arguments (none)
			    	            null); // Order-by clause (ascending by name)
			    	    int file_ColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			    	    int orientation_ColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.ORIENTATION);
			    	    if (cursor.moveToFirst()) {
			    	        String orientation =  cursor.getString(orientation_ColumnIndex);
			    	        File f = new File(cursor.getString(file_ColumnIndex));
			    	        Bitmap img = BitmapFactory.decodeFile(f.getAbsolutePath());
			    	        img = ThumbnailUtils.extractThumbnail(img, 72, 72);
			    	        ImageView v = new ImageView(PlacePlayersActivity.this);
			    	        v.setImageBitmap(img);
			    	        characterView.addView(v);
			    	    }
			    	} finally {
			    	    if (cursor != null) {
			    	        cursor.close();
			    	    }
			    	}
			    } else if (resultCode == RESULT_CANCELED) {
			        Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT);
			    } else {
			        Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT);
			    }
			}
	}
	
	private void invalidateCharacters() {
		((GridView)findViewById(R.id.PCs_for_sides)).setAdapter(new PCSidesAdapter(this));
		//((BaseAdapter)((GridView)findViewById(R.id.PCs_for_sides)).getAdapter()).notifyDataSetChanged();
	}
	
    private OnDragListener onDragPCListener = new View.OnDragListener() {
		public boolean onDrag(View v, DragEvent event) {
			// Defines a variable to store the action type for the incoming event
	        final int action = event.getAction();
	        // Handles each of the expected events
	        switch(action) {
	        	// on return true pour indiquer au systeme qu'on est receveur potentiel
	        	case DragEvent.ACTION_DRAG_STARTED:
                	//v.setAlpha(0.5f);
                    return(true);
	            case DragEvent.ACTION_DRAG_ENTERED:
	            	if (v.getId() == R.id.trash) {
	            		((ImageView)v).getDrawable().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
	            	} else {
	            		((ImageView)v).getDrawable().setColorFilter(0xFF51BA04, PorterDuff.Mode.MULTIPLY);
	            	}
	                v.invalidate();
	                return(true);
                case DragEvent.ACTION_DRAG_EXITED:
                	((ImageView)v).getDrawable().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
	                v.invalidate();
                    return(true);
                case DragEvent.ACTION_DROP:
                    // Gets the item containing the dragged data
                    ClipData.Item item = event.getClipData().getItemAt(0);
                    // Gets the text data from the item.
                    CharSequence dragData = item.getText();
                    int characterId = Integer.parseInt(dragData.toString());
                	helper = new RPGMapperOpenHelper(PlacePlayersActivity.this);
                    if (characterId > 0) {
                    	droppedCharacter = helper.getCharacterById(characterId);
                    }

                    String arrow = "";
                    switch (v.getId()) {
                    case R.id.trash:
	                	((ImageView)v).getDrawable().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
	                	AlertDialog.Builder builder = new AlertDialog.Builder(PlacePlayersActivity.this);
	                	builder.setMessage("Are you sure you want to remove this character ?")
	                	       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
	                	           public void onClick(DialogInterface dialog, int id) {
	            		                if (droppedCharacter != null) {
	            			                helper.deleteCharacter(droppedCharacter.getId());
	            							invalidateCharacters();
	            		                }
	                	           }
	                	       })
	                	       .setNegativeButton("No", new DialogInterface.OnClickListener() {
	                	           public void onClick(DialogInterface dialog, int id) {
	                	                dialog.cancel();
	                	           }
	                	       });
	                	builder.create().show();
                    	break;
                    case R.id.add_char:
            			((ImageView)v).getDrawable().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);

            			characterView = new CharacterView(PlacePlayersActivity.this, droppedCharacter);
            			characterView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
            			characterView.setBtnOKClick(new OnClickListener() {
            				public void onClick(View v) {
    		                    RPGMapperOpenHelper helper = new RPGMapperOpenHelper(PlacePlayersActivity.this);
            					characterView.getUpdatedCharacter().copyTo(droppedCharacter);
            					helper.insertCharacter(droppedCharacter);
            					invalidateCharacters();
                                List<Character> chars = helper.getAllHeroes();
                                for (Character character : chars) {
                        			System.err.println(character.toString());
                        		}
                    			((ViewGroup)findViewById(R.id.container)).removeView(characterView);
            				}
            			});

            			((ViewGroup)findViewById(R.id.container)).addView(characterView);
            			int[] location = new int[2];
            			v.getLocationOnScreen(location);
            			characterView.setPivotX(location[0]+v.getWidth()/2f);
            			characterView.setPivotY(location[1]+v.getHeight()/2f);
            			characterView.setScaleX(0.01f);
            			characterView.setScaleY(0.01f);
            			PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
            			PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
            			ObjectAnimator anim =  ObjectAnimator.ofPropertyValuesHolder(characterView, pvhX, pvhY);
            			anim.setDuration(300);
            			anim.start();
                    	break;
					case R.id.arrow_d:
						arrow = "D";
	                	((ImageView)v).getDrawable().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
		                v.invalidate();
		                if (droppedCharacter != null) {
			                droppedCharacter.setSide(4);
			                helper.updateCharacter(droppedCharacter);
			                invalidateCharacters();
		                }
		    	        SkirmishManager.getInstance().refreshCharacters(PlacePlayersActivity.this);
						break;
					case R.id.arrow_u:
						arrow = "U";
	                	((ImageView)v).getDrawable().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
		                v.invalidate();
		                if (droppedCharacter != null) {
			                droppedCharacter.setSide(2);
			                helper.updateCharacter(droppedCharacter);
			                invalidateCharacters();
		                }
		    	        SkirmishManager.getInstance().refreshCharacters(PlacePlayersActivity.this);
						break;
					case R.id.arrow_l:
						arrow = "L";
	                	((ImageView)v).getDrawable().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
		                v.invalidate();
		                if (droppedCharacter != null) {
			                droppedCharacter.setSide(1);
			                helper.updateCharacter(droppedCharacter);
			                invalidateCharacters();
		                }
		    	        SkirmishManager.getInstance().refreshCharacters(PlacePlayersActivity.this);
						break;
					case R.id.arrow_r:
						arrow = "R";
	                	((ImageView)v).getDrawable().setColorFilter(0xFFFFFFFF, PorterDuff.Mode.MULTIPLY);
		                v.invalidate();
		                if (droppedCharacter != null) {
			                droppedCharacter.setSide(3);
			                helper.updateCharacter(droppedCharacter);
			                invalidateCharacters();
		                }
		    	        SkirmishManager.getInstance().refreshCharacters(PlacePlayersActivity.this);
						break;
					default:
						break;
					}
                    //Toast.makeText(PlacePlayersActivity.this, "Drop " + droppedCharacter.getName() + " dans " + arrow, Toast.LENGTH_LONG).show();
                    List<Character> chars = helper.getAllHeroes();
                    for (Character character : chars) {
            			System.err.println(character.toString());
            		}
                    return(true);
                case DragEvent.ACTION_DRAG_ENDED:
                	//v.setAlpha(1f);
                    return(true);
                // An unknown action type was received.
                default:
                    //Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
	                break;
	        };
	        return false;
		}
	};

	private OnItemClickListener onClickListener = new OnItemClickListener() {
		public void onItemClick(AdapterView<?> adapterView, View v, int arg2, long arg3) {
			selectedCharacter = (Character)v.getTag();
			characterView = new CharacterView(PlacePlayersActivity.this, selectedCharacter);
			characterView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
			characterView.setBtnOKClick(new OnClickListener() {
				public void onClick(View v) {
					RPGMapperOpenHelper helper = new RPGMapperOpenHelper(PlacePlayersActivity.this);
					characterView.getUpdatedCharacter().copyTo(selectedCharacter);
					helper.updateCharacter(selectedCharacter);
					invalidateCharacters();
                    List<Character> chars = helper.getAllHeroes();
                    for (Character character : chars) {
            			System.err.println(character.toString());
            		}
        			((ViewGroup)findViewById(R.id.container)).removeView(characterView);
				}
			});
			characterView.findViewById(R.id.character_thumbnail).setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {
					//define the file-name to save photo taken by Camera activity
					String fileName = "new-photo-name.jpg";
					//create parameters for Intent with filename
					ContentValues values = new ContentValues();
					values.put(MediaStore.Images.Media.TITLE, fileName);
					values.put(MediaStore.Images.Media.DESCRIPTION,"Image capture by camera");
					//imageUri is the current activity attribute, define and save it for later usage (also in onSaveInstanceState)
					imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
					//create new Intent
					Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
					intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
					intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
					startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
				}
			});

			((ViewGroup)findViewById(R.id.container)).addView(characterView);
			int[] location = new int[2];
			v.getLocationOnScreen(location);
			characterView.setPivotX(location[0]+v.getWidth()/2f);
			characterView.setPivotY(location[1]+v.getHeight()/2f);
			characterView.setScaleX(0.01f);
			characterView.setScaleY(0.01f);
			PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
			PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
			ObjectAnimator anim =  ObjectAnimator.ofPropertyValuesHolder(characterView, pvhX, pvhY);
			anim.setDuration(300);
			anim.start();
		}
	};
	
	private OnItemLongClickListener onLongClickListener = new OnItemLongClickListener() {
		public boolean onItemLongClick(AdapterView<?> adapterView, View v, int arg2, long arg3) {
			final ViewGroup vg = (ViewGroup)v;
			final CharSequence text = ""+((Character)v.getTag()).getId();
		    ClipData.Item item = new ClipData.Item(text);
		    ClipData dragData = new ClipData(text, new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
		    DragShadowBuilder myShadow = new DragShadowBuilder(v);
		    //DragShadowBuilder myShadow = new DragShadowBuilder(v);
            v.startDrag(dragData,  // the data to be dragged
                        myShadow,  // the drag shadow builder
                        null,      // no need to use local data
                        0          // flags (not currently used, set to 0)
            );
            
            return true;
		}
	};
	
	private OnClickListener onClickAddCharacterListener = new OnClickListener() {
		public void onClick(View v) {
			selectedCharacter = new Hero();
			characterView = new CharacterView(PlacePlayersActivity.this, new Hero());
			characterView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
			characterView.setBtnOKClick(new OnClickListener() {
				public void onClick(View v) {
                    RPGMapperOpenHelper helper = new RPGMapperOpenHelper(PlacePlayersActivity.this);
					characterView.getUpdatedCharacter().copyTo(selectedCharacter);
					System.err.println("On ajoute " + characterView.getUpdatedCharacter().toString());
					helper.insertCharacter(characterView.getUpdatedCharacter());
					invalidateCharacters();
                    List<Character> chars = helper.getAllHeroes();
                    for (Character character : chars) {
            			System.err.println(character.toString());
            		}
        			((ViewGroup)findViewById(R.id.container)).removeView(characterView);
				}
			});

			((ViewGroup)findViewById(R.id.container)).addView(characterView);
			int[] location = new int[2];
			v.getLocationOnScreen(location);
			characterView.setPivotX(location[0]+v.getWidth()/2f);
			characterView.setPivotY(location[1]+v.getHeight()/2f);
			characterView.setScaleX(0.01f);
			characterView.setScaleY(0.01f);
			PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
			PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
			ObjectAnimator anim =  ObjectAnimator.ofPropertyValuesHolder(characterView, pvhX, pvhY);
			anim.setDuration(300);
			anim.start();

			/*AlertDialog.Builder builder = new AlertDialog.Builder(PlacePlayersActivity.this);
			dialogLayout = inflater.inflate(R.layout.character_dialog, null);
			selectedCharacter = (Character)v.getTag();
			editTextName = (EditText)dialogLayout.findViewById(R.id.name);
			dialogLayout.setBackgroundColor(Color.RED);

			builder.setView(dialogLayout)
					.setPositiveButton("OK", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							RPGMapperOpenHelper helper = new RPGMapperOpenHelper(PlacePlayersActivity.this);
					        helper.insertCharacter(editTextName.getText().toString(), 0);
							invalidateCharacters();
		                    List<Character> chars = helper.getAllCharacters();
		                    for (Character character : chars) {
		            			System.err.println(character.toString());
		            		}
						}
					})
					.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
						}
					});
			builder.create().show();*/
		}
	}; 
	
	private class PCSidesAdapter extends BaseAdapter {
		private List<Character> pcs; 
		private Context context;
		private LayoutInflater inflater;
		private Character selectedCharacter;
		private EditText editTextName;
		
		public PCSidesAdapter(Context context) {
			this.context = context;
			this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			RPGMapperOpenHelper helper = new RPGMapperOpenHelper(context);
			this.pcs = helper.getAllHeroes();
		}
		public int getCount() {
			return pcs.size();
		}
		public Object getItem(int position) {
			return pcs.get(position);
		}
		public long getItemId(int position) {
			return position;
		}
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewGroup view;
			if (convertView == null) {
				view = (ViewGroup)inflater.inflate(R.layout.unknown_character, null);//new TextView(context);
			} else {
				view = (ViewGroup)convertView;
			}
			Character c = pcs.get(position);
			view.setTag(c);
			((TextView)view.findViewById(R.id.name)).setText(c.getName());
			//glView.setOnTouchListener(onTouchDragListener);
			//glView.setOnClickListener(onClickListener);
			//glView.setOnLongClickListener(onLongClickListener);
			view.setOnDragListener(new OnDragListener());
			return view;
		}
		
		private class OnDragListener implements View.OnDragListener {
			public boolean onDrag(View v, DragEvent event) {
				// Defines a variable to store the action type for the incoming event
		        final int action = event.getAction();
		        // Handles each of the expected events
		        // returns false to tell we are not drop receiver
		        switch(action) {
		            case DragEvent.ACTION_DRAG_STARTED:
		                	v.setAlpha(0.5f);
		                    return false;
	                case DragEvent.ACTION_DRAG_ENDED:
	                	v.setAlpha(1f);
	                    return(true);
	                // An unknown action type was received.
	                default:
	                    //Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
		                break;
		        };
		        return false;
			}
		}
	}
}
